/*
 * Copyright (c) 2011 Jean-Marc Perronne
 * Ensisa, 12 rue des Freres Lumieres, F-68093 Mulhouse cedex
 * All rights reserved.
 *
 * The copyright of this software is owned by Werner Randelshofer. 
 * You may not use, copy or modify this software, except in  
 * accordance with the license agreement you entered into with  
 * Jean-Marc Perronne. For details see accompanying license terms. 
 */

package fr.uha.ensisa.jmp.drone.ui.instrument.dial.model;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import fr.uha.ensisa.jmp.ui.model.DefaultBoundedModel;
import fr.uha.ensisa.jmp.ui.utils.ColoredRanges;


public class DefaultDialModel extends DefaultBoundedModel implements DialModel
{
	private boolean paintBackground;
	private boolean paintTicks;
	private boolean paintLabels;
	private boolean paintTrack;

	private int majorTickSpacing;
	private int minorTickSpacing;

	private Map<Integer, String> labelsTable;
	private ColoredRanges labelsColors;
	private ColoredRanges trackColors;
	private ColoredRanges ticksColors;

	private List<ChangeListener> listeners;
	private ChangeEvent changeEvent;

	public DefaultDialModel(int value, int min, int max)
	{
		super(value, min, max);
		this.listeners = new ArrayList<ChangeListener>();
		this.changeEvent = new ChangeEvent(this);
		this.paintBackground = true;
		this.paintTicks = false;
		this.paintLabels = false;
		this.paintTrack = false;
		this.majorTickSpacing = 0;
		this.minorTickSpacing = 0;
		this.labelsTable = null;
		this.labelsColors = null;
		this.trackColors = null;
		this.ticksColors = null;
	}
	
	public DefaultDialModel()
	{
		this(0,0,0);
	}
	
	@Override
	public void addChangeListener(ChangeListener l)
	{
		this.listeners.add(l);
	}

	@Override
	public void removeChangeListener(ChangeListener l)
	{
		this.listeners.remove(l);
	}

	protected void fireStateChanged()
	{
		for (ChangeListener l : this.listeners)
			l.stateChanged(changeEvent);
	}

	@Override
	public boolean getPaintBackground()
	{
		return this.paintBackground;
	}

	@Override
	public void setPaintBackground(boolean v)
	{
		if (this.paintBackground != v)
		{
			this.paintBackground = v;
			this.fireStateChanged();
		}
	}

	@Override
	public boolean getPaintTicks()
	{
		return this.paintTicks;
	}

	@Override
	public void setPaintTicks(boolean v)
	{
		if (this.paintTicks != v)
		{
			this.paintTicks = v;
			this.fireStateChanged();
		}
		
	}

	@Override
	public boolean getPaintLabels()
	{
		return this.paintLabels;
	}

	@Override
	public void setPaintLabels(boolean v)
	{
		// if (labelTable == null && getMajorTickSpacing() > 0)
		// {
		// setLabelTable(createStandardLabels(getMajorTickSpacing()));
		// }
		if (this.paintLabels != v)
		{
			this.paintLabels = v;
			this.fireStateChanged();
		}
	}

	@Override
	public boolean getPaintTrack()
	{
		return this.paintTrack;
	}

	@Override
	public void setPaintTrack(boolean v)
	{
		if (this.paintTrack != v)
		{
			this.paintTrack = v;
			this.fireStateChanged();
		}
	}

	@Override
	public Map<Integer, String> getLabelsTable()
	{
		return this.labelsTable;
	}

	@Override
	public void setLabelTable(Map<Integer, String> labels)
	{
		if (this.labelsTable != labels)
		{
			this.labelsTable = labels;
			this.fireStateChanged();
		}		
	}

	@Override
	public void setLabelsColors(ColoredRanges labelsColors)
	{
		if (labelsColors != this.labelsColors)
		{
			this.labelsColors = labelsColors;
			this.fireStateChanged();
		}		
	}

	@Override
	public ColoredRanges getLabelsColors()
	{
		return this.labelsColors;
	}

	@Override
	public void setTrackColors(ColoredRanges trackColors)
	{
		if (this.trackColors != trackColors)
		{
			this.trackColors = trackColors;
			this.fireStateChanged();
		}
		
	}

	@Override
	public ColoredRanges getTrackColors()
	{
		return this.trackColors;
	}

	@Override
	public void setTicksColors(ColoredRanges ticksColors)
	{
		if (this.ticksColors != ticksColors)
		{
			this.ticksColors = ticksColors;
			this.fireStateChanged();
		}
		
	}

	@Override
	public ColoredRanges getTicksColors()
	{
		return this.ticksColors;
	}

	@Override
	public int getMajorTickSpacing()
	{
		return this.majorTickSpacing;
	}

	@Override
	public void setMajorTickSpacing(int v)
	{
		if (this.majorTickSpacing != v)
		{
			this.majorTickSpacing = v;
			this.fireStateChanged();
		}
	}

	@Override
	public int getMinorTickSpacing()
	{
		return this.minorTickSpacing;
	}

	@Override
	public void setMinorTickSpacing(int v)
	{
		if (this.minorTickSpacing != v)
		{
			this.minorTickSpacing = v;
			this.fireStateChanged();
		}		
	}
	protected Map<Integer, String> createStandardLabels(int increment, int start)
	{
		if ( start > this.getMaximum() || start < this.getMinimum() ) {
            throw new IllegalArgumentException( "Dial label start point out of range." );
        }

        if ( increment <= 0 ) {
            throw new IllegalArgumentException( "Dial incremement must be > 0" );
        }

		Map<Integer, String> labels = new TreeMap<Integer, String>();
		for (int labelIndex = start; labelIndex <= this.getMaximum(); labelIndex += increment)
		{
			labels.put(new Integer(labelIndex), String.valueOf(labelIndex));
		}
		return labels;
	}

	public Map<Integer, String> createStandardLabels(int increment)
	{
		return this.createStandardLabels(increment, this.getMinimum());
	}

}
